﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;

namespace PB.Airsoft.NHibernateWrapper
{
    public class SessionCreator : ISessionCreator
    {
        private static object lockObj = new object();

        private const string ConnectionConfigKey = "connection.connection_string";

        private NHibernate.Cfg.Configuration config;
        private Dictionary<string, ISessionFactory> factories;

        public SessionCreator()
        {
            factories = new Dictionary<string, ISessionFactory>();
            try
            {
                config = new NHibernate.Cfg.Configuration();
                config.Configure();
            }
            catch (Exception ex)
            {
                throw new Exception("Could not configure NHibernate. Check that the correct data mapping file is not missing " +
                                        "and that the correct NHibernate configuration exists in the config file.", ex);
            }
        }

        public virtual ISession Create(string connectionString)
        {
            ISession result = GetFactory(connectionString).OpenSession();
            result.FlushMode = FlushMode.Commit;
            return result;
        }

        private ISessionFactory GetFactory(string connectionString)
        {
            ISessionFactory factory = null;
            if (!factories.TryGetValue(connectionString, out factory))
            {
                lock (lockObj)
                {
                    if (!factories.TryGetValue(connectionString, out factory))
                    {
                        config.Properties[ConnectionConfigKey] = connectionString;
                        try
                        {
                            factory = config.BuildSessionFactory();
                        }
                        catch (Exception ex)
                        {
                            throw new Exception(@"Could not create NHibernate SessionFactory instance from the configuration provided. 
                                Most common reasons are: 
                                wrong 'hibernate-configuration' section in web.config; 
                                missing or wrong class names in mapping files (check that the mapped class exists, and its name is correct when defining 'return' mapping element for 'sql-query' elements).", ex);
                        }
                        factories.Add(connectionString, factory);
                    }
                }
            }
            return factory;
        }
    }
}
